<!DOCTYPE html><html class="appearance-auto" lang="zh-CN"><head><meta charset="UTF-8"><title>【Spring源码解析系列】 autowiring原理</title><meta name="description" content="用创业者心态做好每一件事情！"><meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, initial-scale=1"><!-- Google Analytics --><!-- End Google Analytics -->
<!-- Baidu Analytics --><!-- End Baidu Analytics --><link rel="icon" href="/blog/images/favicon.png"><link rel="stylesheet" href="/blog/style/common/bulma.css"><link rel="stylesheet" href="/blog/style/base.css"><link rel="stylesheet" href="/blog/style/common/helper.css"><script src="/blog/js/common.js"></script><link rel="stylesheet" href="/blog/style/post.css"><link rel="stylesheet" href="/blog/style/themes/highlight-theme-light.css"><script src="/blog/js/highlight.pack.js"></script><meta name="description" content="
本文主要讲述Spring中autowiring原理


SpringIOC容器中提供了两种管理Bean依赖关系的方式：1、显式管理：通过BeanDefinition的属性值和构造方法实现Bean依赖关系管理；2、autowiring：SpringIOC容器中的依赖自动装配功能，不需要对Bean属性的依赖关系做显式的声明，只需要在配置好的autowiring属性，IOC容器会自动使用反射查找属性的类型和名称，然后基于属性的类型或者名称来自动匹配容器中管理的Bean，从而自动地完成依赖注入。容器对Bean实例对象的属性注入的处理发生在AbstractAutoWireCapableBeanFactory类中的populateBean方法中。
//将Bean属性设置到生成的实例对象上
protected void.."><!-- hexo injector head_end start -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hexo-math@4.0.0/dist/style.css">
<!-- hexo injector head_end end --><meta name="generator" content="Hexo 5.4.1"><link rel="alternate" href="/blog/atom.xml" title="janedler's blog" type="application/atom+xml">
</head><body class="is-flex is-flex-direction-column"><header class="header-widget is-flex-shrink-0 is-hidden-mobile"><div class="container is-fullhd is-flex is-justify-content-space-between is-align-items-center is-full-height"><section class="is-hidden-mobile is-flex-shrink-0"><h2><a href="/blog/">田园牧歌(*︶*)'s blog</a></h2></section><h3 class="is-hidden-mobile is-family-serif is-full-height is-flex is-align-items-center is-flex-shrink-0"><div class="is-full-height" id="postTopic"><p class="is-full-height is-flex-shrink-0 is-flex is-align-items-center is-justify-content-center">【Spring源码解析系列】 autowiring原理</p><p class="is-full-height is-flex-shrink-0 is-flex is-align-items-center is-justify-content-center">点击返回顶部</p></div></h3><aside class="is-flex-shrink-0"><h3 class="is-inline-block"><a href="/blog/">首页</a></h3><h3 class="is-inline-block"><a href="/blog/about">关于</a></h3><h3 class="is-inline-block"><a href="/blog/archives">归档</a></h3></aside></div></header><header class="is-flex header-widget is-flex-shrink-0 is-align-items-center is-justify-content-center is-hidden-tablet"><h3 class="is-inline-block"><a href="/blog/">首页</a></h3><h3 class="is-inline-block"><a href="/blog/about">关于</a></h3><h3 class="is-inline-block"><a href="/blog/archives">归档</a></h3></header><main><main class="container is-max-widescreen content section post-page pt-4 px-4"><div class="columns is-flex-desktop is-justify-content-center is-flex-direction-row-reverse"><div class="column is-3 is-hidden-mobile is-hidden"></div><div class="column is-9"><header class="my-4"><a href="/blog/tags/Java"><i class="tag post-item-tag">Java</i></a><a href="/blog/tags/Spring"><i class="tag post-item-tag">Spring</i></a></header><h1 class="mt-0 mb-1 is-family-serif" id="postTitle">【Spring源码解析系列】 autowiring原理</h1><time class="has-text-grey" datetime="2022-11-30T16:00:00.000Z">2022-12-01</time><article class="mt-2 post-content"><p><img src="https://janedler.oss-cn-beijing.aliyuncs.com/images/spring.png" alt="cover"></p>
<p>本文主要讲述Spring中autowiring原理</p>
<span id="more"></span>

<p>SpringIOC容器中提供了两种管理Bean依赖关系的方式：<br>1、显式管理：通过BeanDefinition的属性值和构造方法实现Bean依赖关系管理；<br>2、autowiring：SpringIOC容器中的依赖自动装配功能，不需要对Bean属性的依赖关系做显式的声明，只需要在配置好的autowiring属性，IOC容器会自动使用反射查找属性的类型和名称，然后基于属性的类型或者名称来自动匹配容器中管理的Bean，从而自动地完成依赖注入。<br>容器对Bean实例对象的属性注入的处理发生在AbstractAutoWireCapableBeanFactory类中的populateBean方法中。</p>
<pre><code class="java">//将Bean属性设置到生成的实例对象上
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) &#123;
   ...忽略...
   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   //依赖注入开始，首先处理autowire自定装配的注入
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) &#123;
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      //对autowire自动装配的处理，根据Bean的名称自动装配注入
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) &#123;
         autowireByName(beanName, mbd, bw, newPvs);
      &#125;
      // Add property values based on autowire by type if applicable.
      //根据Bean类型自动装配注入
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) &#123;
         autowireByType(beanName, mbd, bw, newPvs);
      &#125;
      pvs = newPvs;
   &#125;
   ...忽略...
&#125;
</code></pre>
<p>SpringIOC容器根据Bean名称或者类型进行autowiring自动依赖注入：</p>
<pre><code class="java">//根据名称对属性进行自动依赖注入
protected void autowireByName(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) &#123;
   //对Bean对象中非简单属性（不是简单继承的对象）进行处理
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) &#123;
      //如果SpringIOC容器中包含指定名称的Bean
      if (containsBean(propertyName)) &#123;
         //调用getBean方法向IOC容器索取指定名称的Bean实例，迭代触发属性的初始化和依赖注入
         Object bean = getBean(propertyName);
         //为指定名称的属性赋予属性值
         pvs.add(propertyName, bean);
         //指定名称属性注册依赖Bean名称，进行属性依赖注入
         registerDependentBean(propertyName, beanName);
         if (logger.isTraceEnabled()) &#123;
            logger.trace(&quot;Added autowiring by name from bean name &#39;&quot; + beanName +
                  &quot;&#39; via property &#39;&quot; + propertyName + &quot;&#39; to bean named &#39;&quot; + propertyName + &quot;&#39;&quot;);
         &#125;
      &#125;
      else &#123;
         if (logger.isTraceEnabled()) &#123;
            logger.trace(&quot;Not autowiring property &#39;&quot; + propertyName + &quot;&#39; of bean &#39;&quot; + beanName +
                  &quot;&#39; by name: no matching bean found&quot;);
         &#125;
      &#125;
   &#125;
&#125;
</code></pre>
<pre><code class="java">//根据类型对属性进行自动依赖注入
protected void autowireByType(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) &#123;
   //获取用户定义的类型转换器
   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) &#123;
      converter = bw;
   &#125;
   //存放解析的要注入的属性
   Set&lt;String&gt; autowiredBeanNames = new LinkedHashSet&lt;&gt;(4);
   //对Bean对象中非简单属性进行处理
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) &#123;
      try &#123;
         //获取指定属性名称的属性描述器
         PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
         // Don&#39;t try autowiring by type for type Object: never makes sense,
         // even if it technically is an unsatisfied, non-simple property.
         //不对Object类型的属性进行autowiring自动依赖注入
         if (Object.class != pd.getPropertyType()) &#123;
            MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
            // Do not allow eager init for type matching in case of a prioritized post-processor.
            boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
            DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
            Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
            if (autowiredArgument != null) &#123;
               pvs.add(propertyName, autowiredArgument);
            &#125;
            for (String autowiredBeanName : autowiredBeanNames) &#123;
               registerDependentBean(autowiredBeanName, beanName);
               if (logger.isTraceEnabled()) &#123;
                  logger.trace(&quot;Autowiring by type from bean name &#39;&quot; + beanName + &quot;&#39; via property &#39;&quot; +
                        propertyName + &quot;&#39; to bean named &#39;&quot; + autowiredBeanName + &quot;&#39;&quot;);
               &#125;
            &#125;
            autowiredBeanNames.clear();
         &#125;
      &#125;
      catch (BeansException ex) &#123;
         throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
      &#125;
   &#125;
&#125;
</code></pre>
<p>通过源码分析，真正实现属性注入的是DefaultSingletonBeanRegistry类的registerDependentBean方法</p>
<pre><code class="java">//为指定的Bean注入依赖的Bean
public void registerDependentBean(String beanName, String dependentBeanName) &#123;
   //处理Bean名称，将别名转换为规范的Bean名称
   String canonicalName = canonicalName(beanName);
   //多线程同步，保证容器内数据的一致性
   //先从容器中：bean名称---&gt;全部依赖Bean名称集合找查找给定名称Bean的依赖Bean
   synchronized (this.dependentBeanMap) &#123;
      //获取给定名称Bean的所有依赖Bean名称
      Set&lt;String&gt; dependentBeans =
            this.dependentBeanMap.computeIfAbsent(canonicalName, k -&gt; new LinkedHashSet&lt;&gt;(8));
      //向容器中：bean名称---&gt;全部依赖Bean名称集合添加Bean的依赖信息
      //即，将Bean所依赖的Bean添加到容器的集合中
      if (!dependentBeans.add(dependentBeanName)) &#123;
         return;
      &#125;
   &#125;
   //从容器中：bean名称---&gt;指定名称Bean的依赖集合找查找给定名称Bean的依赖Bean
   synchronized (this.dependenciesForBeanMap) &#123;
      Set&lt;String&gt; dependenciesForBean =
            this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -&gt; new LinkedHashSet&lt;&gt;(8));
      //向容器中：bean名称---&gt;指定Bean的依赖Bean名称集合添加Bean的依赖信息
      //即：将Bean所依赖的Bean添加到容器的集合中
      dependenciesForBean.add(canonicalName);
   &#125;
&#125;
</code></pre>
<p>autowiring的实现过程：</p>
<p>1、对Bean的属性代调用getBean方法，完成依赖Bean的初始化和依赖注入。<br>2、将依赖Bean的属性引用设置到被依赖的Bean属性上。<br>3、将依赖Bean的名称和被依赖Bean的名称存储在IOC容器的集合中。</p>
</article><section class="jump-container is-flex is-justify-content-space-between my-6"><!-- em is empty placeholder--><a class="button is-default" href="/blog/2022/12/01/Spring/Spring-Bean%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/" title="【Spring源码解析系列】 Bean生命周期"><i class="iconfont icon-prev mr-2 has-text-grey"></i><span class="has-text-weight-semibold">上一页: 【Spring源码解析系列】 Bean生命周期</span></a><a class="button is-default" href="/blog/2022/12/01/Spring/Spring-lookup-method%E5%92%8Creplaced-method/" title="【Spring源码解析系列】 lookup-method和replaced-method"><span class="has-text-weight-semibold">下一页: 【Spring源码解析系列】 lookup-method和replaced-method</span><i class="iconfont icon-next ml-2 has-text-grey"></i></a></section><article class="mt-6 comment-container"><script async repo="janedler/blog" src="https://utteranc.es/client.js" issue-term="pathname" theme="preferred-color-scheme"></script></article></div></div></main></main><footer class="is-flex is-flex-direction-column is-align-items-center is-flex-shrink-0 is-family-serif"><section class="sns-container"><!-- Github--><a title="github" target="_blank" rel="noopener nofollow" href="//github.com//janedler"><i class="iconfont icon-github"></i></a><!-- Ins--><!-- RSS--><a title="rss" target="_blank" rel="noopener nofollow" href="/blog/atom.xml"><i class="iconfont icon-rss"></i></a><!-- 知乎--><!-- 领英--><!-- 脸书--></section><p><span>Copyright ©</span><span> 田园牧歌(*︶*) 2022</span></p><div class="is-flex is-justify-content-center is-flex-wrap-wrap"><p>Powered by Hexo &verbar;&nbsp;</p><p class="is-flex is-justify-content-center"><a title="Hexo theme author" target="_blank" rel="noopener" href="//github.com/haojen">Theme by Haojen&nbsp;</a></p><div style="margin-top: 2px"><a class="github-button" title="github-button" target="_blank" rel="noopener" href="https://github.com/haojen/hexo-theme-Claudia" data-color-scheme="no-preference: light; light: light; dark: dark;" data-show-count="true"></a></div></div><div><span></span></div></footer><script async defer src="https://buttons.github.io/buttons.js"></script><script src="/blog/js/post.js"></script></body></html>